package com.sharer.last.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sharer.last.base.model.PageVO;
import com.sharer.last.base.support.QueryCondition;
import com.sharer.last.base.enums.BusinessExceptionCode;
import com.sharer.last.base.enums.ExceptionPrefixParamEnum;
import com.sharer.last.base.exception.BusinessException;
import com.sharer.last.base.utils.CollectionUtil;
import com.sharer.last.mapper.CategoryMapper;
import com.sharer.last.model.dto.category.CategoryChangeDTO;
import com.sharer.last.model.dto.category.CategoryQueryDTO;
import com.sharer.last.model.po.CategoryPO;
import com.sharer.last.model.vo.category.CategoryVO;
import com.sharer.last.service.BlogService;
import com.sharer.last.service.CategoryService;
import com.sharer.last.utils.BeanUtil;
import com.sharer.last.base.utils.ConvertUtil;
import com.sharer.last.base.utils.StringUtil;
import com.sharer.last.wrapper.CategoryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 博客分类业务层实现
 *
 * @ClassName CategoryServiceImpl
 * @Author wangjin
 * @Date 2023/5/5 20:44
 * @Description
 * @Version 1.0
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, CategoryPO> implements CategoryService {
    @Resource
    CategoryWrapper categoryWrapper;

    @Resource
    BlogService blogService;


    private LambdaQueryWrapper<CategoryPO> buildQueryWrapper(CategoryQueryDTO queryDTO) {
        LambdaQueryWrapper<CategoryPO> qw = new LambdaQueryWrapper<>();
        qw.orderByAsc(CategoryPO::getId);
        return qw;
    }

    /**
     * 根据分类名称查询数据
     *
     * @param categoryName
     * @return
     */
    @Override
    public CategoryPO getByCategoryName(String categoryName) {
        LambdaQueryWrapper<CategoryPO> qw = new LambdaQueryWrapper<>();
        if (StringUtil.isBlank(categoryName)) {
            throw new BusinessException(BusinessExceptionCode.NAME_IS_BLANK, ExceptionPrefixParamEnum.CATEGORY);
        }
        qw.eq(CategoryPO::getCategoryName, categoryName);
        return this.getOne(qw);
    }

    /**
     * 根据id查询数据
     *
     * @param id 主键
     * @return
     */
    @Override
    public CategoryVO findById(Long id) {
        CategoryPO category = this.getById(id);
        if (category == null) {
            return null;
        }
        return categoryWrapper.entityVO(category);
    }

    /**
     * 根据分类名称查询数据
     *
     * @param name 分类名称
     * @return
     */
    @Override
    public CategoryVO findByCategoryName(String name) {
        CategoryPO one = this.getByCategoryName(name);
        if (one == null) {
            return null;
        }
        return categoryWrapper.entityVO(one);
    }

    /**
     * 分页查询
     *
     * @param queryDTO 请求参数
     * @return
     */
    @Override
    public PageVO<CategoryVO> selectListByPage(CategoryQueryDTO queryDTO) {
        LambdaQueryWrapper<CategoryPO> qw   = this.buildQueryWrapper(queryDTO);
        IPage<CategoryPO>              page = this.page(QueryCondition.getPage(queryDTO.getPage()), qw);
        return categoryWrapper.toPageVO(page);
    }

    /**
     * 查询所有分类数据
     *
     * @return
     */
    @Override
    public List<CategoryPO> queryList(CategoryQueryDTO queryDTO) {
        LambdaQueryWrapper<CategoryPO> qw = this.buildQueryWrapper(queryDTO);
        return this.list(qw);
    }

    /**
     * 查询所有分类数据
     *
     * @return
     */
    @Override
    public List<CategoryVO> selectAllList() {
        List<CategoryPO> categoryPOS = this.list();
        if (CollectionUtil.isNotEmpty(categoryPOS)) {
            return categoryWrapper.listVO(categoryPOS);
        }
        return new ArrayList<>();
    }

    /**
     * 新增分类
     *
     * @param categoryChangeDTO 分类数据
     * @return
     */
    @Override
    public void createCategory(CategoryChangeDTO categoryChangeDTO) {
        CategoryPO categoryPO = this.getByCategoryName(categoryChangeDTO.getCategoryName());
        if (categoryPO != null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EXIST, ExceptionPrefixParamEnum.CATEGORY);
        }
        CategoryPO category = BeanUtil.copy(categoryChangeDTO, CategoryPO.class);
        category.setId(null);
        if (this.save(category)) {
            throw new BusinessException(BusinessExceptionCode.DATA_INSERT_FAIL, ExceptionPrefixParamEnum.CATEGORY);
        }
    }

    /**
     * 新增分类
     *
     * @param categoryName 分类名称
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public CategoryPO createCategory(String categoryName) {
        CategoryPO categoryPO = this.getByCategoryName(categoryName);
        if (categoryPO == null) {
            // 新建分类
            CategoryPO category = CategoryPO.builder().categoryName(categoryName).build();
            if (!this.save(category)) {
                throw new BusinessException(BusinessExceptionCode.DATA_INSERT_FAIL, ExceptionPrefixParamEnum.CATEGORY);
            }
            categoryPO = category;
        }
        return categoryPO;
    }

    /**
     * 更新分类
     *
     * @param dto 分类数据
     * @return
     */
    @Override
    public void updateCategory(CategoryChangeDTO dto) {
        // 校验id
        if (ConvertUtil.toInt(dto.getId()) < 1) {
            throw new BusinessException(BusinessExceptionCode.ID_IS_NULL, ExceptionPrefixParamEnum.CATEGORY);
        }
        // 校验类别是否存在
        String     categoryName = dto.getCategoryName();
        CategoryPO category     = this.getByCategoryName(categoryName);
        if (category != null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EXIST, ExceptionPrefixParamEnum.CATEGORY);
        }
        // 更新操作
        CategoryPO categoryPO = BeanUtil.copy(dto, CategoryPO.class);
        if (!this.updateById(categoryPO)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.CATEGORY);
        }
    }

    /**
     * 删除分类数据
     *
     * @param id 主键id
     * @return
     */
    @Override
    public void deleteCategoryById(Long id) {
        // 首先校验数据是否存在
        CategoryPO categoryPO = this.getById(id);
        if (categoryPO == null) {
            throw new BusinessException(BusinessExceptionCode.DATA_IS_EMPTY, ExceptionPrefixParamEnum.CATEGORY);
        }
        // 校验是否和博客存在关联
        if (blogService.getBlogNumByCategoryId(id) > 0) {
            throw new BusinessException(BusinessExceptionCode.CATEGORY_HAS_BLOG_EXIST_RELATEDNESS);
        }
        // 删除数据
        if (!this.removeById(id)) {
            throw new BusinessException(BusinessExceptionCode.DATA_REMOVE_FAIL, ExceptionPrefixParamEnum.CATEGORY);
        }
    }

}
